import json
import random
import string
import time

from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.decorators import authentication_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from commodity.models import CommodityInfos
from shopper.form import LoginForm, LoginModelForm
from shopper.models import OrderInfos, CartInfos
from shopper.pays import get_pay
from shopper.serializers import OrderInfosSerializer, CartInfosSerializer


# Create your views here.



class loginView(APIView):
    """
    用户登录视图函数，处理用户登录请求，
    支持现有用户认证和新用户注册
    """
    authentication_classes = []
    permission_classes = []

    def post(self, request):
        context = {"state":"fail", "msg":"注册或登录失败"}
        json_str = json.loads(request.body.decode())
        infos = LoginModelForm(data=json_str)
        d = infos.data
        username = d['username']
        password = d['password']
        last_login = ''
        if User.objects.filter(username=username).first():
            # 验证账号和密码是否与模型User中对应的一致
            user = authenticate(username=username, password=password)
            # 如果通过验证，使用内置函数login执行登录操作，登录成功后
            # 跳转到个人中心页面
            if user:
                login(request, user)
                last_login = user.last_login
                context = {"state":"success", "msg":"登录成功"}
        else:
            context = {'state': 'success', 'msg': '注册成功'}
            d = dict(username=username, password=password, is_staff=1, is_active=1)
            user = User.objects.create_user(**d)
            user.save()
            login(request, user)
        context['username'] = username
        context['last_login'] = last_login
        return Response(context)


class MySessionAuthentication(SessionAuthentication):
    """
    自定义SessionAuthentication,取消CSRF验证
    """
    def authenticate(self, request):
        user = getattr(request._request, 'user', None)
        if not user or not user.is_active:
            return None
        return (user, None)


class logoutView(APIView):
    authentication_classes = [MySessionAuthentication, BasicAuthentication]
    permission_classes = [IsAuthenticated]
    def post(self, request):
        context = {"state":"fail", "msg":"退出失败"}
        if request.user.username:
            logout(request)
            context = {"state":"success", "msg":"退出成功"}
        return Response(context)


class shopperView(APIView):
    authentication_classes = [MySessionAuthentication, BasicAuthentication]
    permission_classes = [IsAuthenticated]

    def get(self, request):
        context = {'state':'success', 'msg':'获取成功', 'data':{}}
        t = request.GET.get('t', '')
        payTime = request.session.get('payTime', '')
        # 从session中获取并处理已支付的订单信息，并写入订单信息表
        if t and payTime and t==payTime:
            payInfo = request.session.get('payInfo', '')
            OrderInfos.objects.create(**payInfo)
            del request.session['payInfo']
            del request.session['payTime']
        # 根据当前用户查询用户所有订单信息
        orders = OrderInfos.objects.filter(user_id=request.user.id).order_by('-created').all()
        context['data']['orders'] = OrderInfosSerializer(instance=orders, many=True).data
        return Response(context)



class shopcartView(APIView):
    authentication_classes = [MySessionAuthentication, BasicAuthentication]
    permission_classes = [IsAuthenticated]
    def get(self, request):
        context = {'state':'success', 'msg':'获取成功', 'data':{}}
        # 根据当前用户查找购车信息
        c = CartInfos.objects.filter(user_id=request.user.id).all()
        context['data'] = CartInfosSerializer(instance=c, many=True).data
        return Response(context)
    def post(self, request):
        context = {'state':'fail', 'msg':'加购失败'}
        json_str = json.loads(request.body.decode())
        id = json_str.get('id', '')
        quantity = json_str.get('quantity', 1)
        userID = request.user.id
        commodityInfos = CommodityInfos.objects.filter(id=id).first()
        if id and commodityInfos and quantity:
            d = dict(commodityInfos_id=commodityInfos,user_id = userID,
                     quantity=quantity)
            f = dict(commodityInfos_id=commodityInfos,user_id = userID)
            CartInfos.objects.update_or_create(d, **f)
            context = {'state':'success', 'msg':'加购成功'}
        return Response(context)



class deleteAPI(APIView):
    """
    购物车删除API视图函数
    处理购物车的删除商品请求，支持按用户删除和按商品id删除
    """
    authentication_classes = [MySessionAuthentication, BasicAuthentication]
    permission_classes = [IsAuthenticated]
    def post(self, request):
        context = {'state':'success', 'msg':'删除成功'}
        json_str = json.loads(request.body.decode())
        username = json_str.get('username', '')
        carId = json_str.get('carId', '')
        if username:
            CartInfos.objects.filter(user_id=request.user.id).filter(id=carId).delete()
        elif carId:
            CartInfos.objects.filter(id=carId).delete()
        else:
            context = {'state':'fail', 'msg':'删除失败'}
        return Response(context)



class paysView(APIView):
    authentication_classes = [MySessionAuthentication, BasicAuthentication]
    permission_classes = [IsAuthenticated]
    def post(self, request):
        context = {'state':'fail', 'msg':'支付失败', 'data':{}}
        json_str = json.loads(request.body.decode())
        total = json_str.get('total', 0)
        total = float(str(total).replace("￥", ''))
        if total:
            out_trade_no = str(int(time.time()))
            user_id = request.user.id
            payInfo = dict(price=total, user_id=user_id, status='已支付')
            request.session['payInfo'] = payInfo
            request.session['payTime'] = out_trade_no
            return_url = 'http://localhost:8010/#/shopper'
            data = get_pay(out_trade_no, total, return_url)
            context = {'state':'success', 'msg':'支付成功', 'data':data}
        return Response(context)